#pragma once
#include "fields.hpp"
#include <memory>
#include <functional>
/*
    BaseMessage
    BaseBuffer
    BaseProtocol
    BaseConnection
    BaseClient
    BaseServer
*/

namespace jsonrpc
{
    // 1.BaseMessage
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;

        virtual ~BaseMessage(){}
        // 设置属性
        virtual void setId(const std::string& id){ _rid = id;}
        virtual void setMType(const MType& type){ _mtype = type;}
        // 返回属性
        virtual std::string rid(){return _rid;}
        virtual MType rMType(){return _mtype;}
        // 序列化 反序列化   
        virtual std::string serialize() = 0;  
        virtual bool unserialize(const std::string &msg) = 0;
        virtual bool check() = 0;

    private:
        MType _mtype;
        std::string _rid;
    };
    
    // 2.BaseBuffer
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;
        virtual size_t  readableBytes() = 0; // 能从缓冲区读多少字节
        virtual int32_t peekInt32() = 0; // 读4个字节的数据, 不会从缓冲区中拿出来
        virtual int32_t readInt32() = 0; // 拿出4个字节
        virtual void retrieveInt32() = 0; // 跳过4个字节
        virtual std::string retrieveAsString(size_t len) = 0; // 根据长度取出指定数据
    };

    // 3.BaseProtocol
    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;

        // 接收数据的处理
        virtual bool canProcessed(const BaseBuffer::ptr& buf) = 0; // 是否能处理数据(是否完整)
        virtual bool onMessage(const BaseBuffer::ptr& buf, BaseMessage::ptr& msg) = 0; // 给出buff, 还一个msg

        // 发送数据的处理
        virtual std::string serialize(const BaseMessage::ptr& msg) = 0; //将消息序列化完后, 返回一个字符串
    };
    
    // 4.BaseConnection
    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        virtual void send(const BaseMessage::ptr& msg) = 0;
        virtual void shutdown() = 0;   // 关闭连接
        virtual bool connected() = 0;  // 连接是否建立
    };
    
    // 5.BaseServer
    using ConnectionCallback = std::function<void(const BaseConnection::ptr&)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr&)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr&, BaseMessage::ptr&)>;

    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;
        virtual void setConnectionCallback(const ConnectionCallback cb) { _cb_connection = cb;}
        virtual void setCloseCallback(const CloseCallback cb) { _cb_close = cb;}
        virtual void setMessageCallback(const MessageCallback cb) { _cb_message = cb;}
        virtual void start() = 0;

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };

    // 6.BaseClient
    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;
        virtual void setConnectionCallback(const ConnectionCallback cb) { _cb_connection = cb;}
        virtual void setCloseCallback(const CloseCallback cb) { _cb_close = cb;}
        virtual void setMessageCallback(const MessageCallback cb) { _cb_message = cb;}
        virtual void connect() = 0; // 连接服务器
        virtual bool connected() = 0;   // 连接是否建立
        virtual void shutdown() = 0;    // 关闭连接
        virtual BaseConnection::ptr connection() = 0; // 获取连接
        virtual bool send(const BaseMessage::ptr& msg) = 0; // 发送消息

    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
}

